package org.truenewx.tnxjee.model.spec.menu;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.truenewx.tnxjee.model.spec.user.security.UserConfigAuthority;

/**
 * 菜单项
 *
 * @author jianglei
 */
public class MenuItem {

    private String name;
    private String caption;
    private String desc;
    /**
     * 配置权限限定集
     */
    private Collection<UserConfigAuthority> authorities;
    /**
     * 可否参与权限分配，所有用户均可使用和仅超管可使用的菜单项理应不可参与权限分配
     */
    private Boolean assignable;
    /**
     * 可否再编辑，在允许用户更改菜单项的场景中使用，默认为null时不可再编辑
     */
    private Boolean editable;
    private MenuItem[] subs;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCaption() {
        return this.caption;
    }

    public void setCaption(String caption) {
        this.caption = caption;
    }

    public String getDesc() {
        return this.desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public Collection<UserConfigAuthority> getAuthorities() {
        return this.authorities;
    }

    public void setAuthorities(Collection<UserConfigAuthority> authorities) {
        this.authorities = authorities;
    }

    public Boolean getAssignable() {
        return this.assignable;
    }

    public void setAssignable(Boolean assignable) {
        this.assignable = assignable;
    }

    public Boolean getEditable() {
        return this.editable;
    }

    public void setEditable(Boolean editable) {
        this.editable = editable;
    }

    public MenuItem[] getSubs() {
        return this.subs;
    }

    public void setSubs(MenuItem[] subs) {
        this.subs = subs;
    }

    //////

    public String getPermission() {
        if (this.assignable != Boolean.FALSE && this.authorities != null) {
            for (UserConfigAuthority authority : this.authorities) {
                String permission = authority.getPermission();
                if (StringUtils.isNotBlank(permission)) {
                    return permission;
                }
            }
        }
        return null;
    }

    public MenuItem cloneWithoutSubs() {
        MenuItem other = new MenuItem();
        other.setName(getName());
        other.setCaption(getCaption());
        other.setDesc(getDesc());
        other.setAssignable(getAssignable());
        other.setEditable(getEditable());
        Collection<UserConfigAuthority> authorities = getAuthorities();
        if (authorities != null) {
            other.setAuthorities(authorities.stream().map(UserConfigAuthority::clone).collect(Collectors.toList()));
        }
        return other;
    }

    public List<MenuItem> getChainByPermission(String permission) {
        if (permission.equals(getPermission())) {
            return List.of(this);
        } else if (this.subs != null) {
            List<MenuItem> chain = new ArrayList<>();
            for (MenuItem sub : this.subs) {
                List<MenuItem> subChain = sub.getChainByPermission(permission);
                if (CollectionUtils.isNotEmpty(subChain)) {
                    chain.add(this);
                    chain.addAll(subChain);
                    return chain;
                }
            }
        }
        return null;
    }

    public boolean containsAuthority() {
        if (CollectionUtils.isNotEmpty(this.authorities)) {
            return true;
        }
        if (this.subs != null) {
            for (MenuItem sub : this.subs) {
                if (sub.containsAuthority()) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return "MenuItem{name='" + this.name + "', caption='" + this.caption + "'}";
    }

}
